package cn.com.transfer.params;

import cn.com.transfer.utils.IcbcNative;
import org.nutz.mvc.annotation.Param;
import org.xvolks.jnative.exceptions.NativeException;

import java.lang.reflect.Field;
import java.util.Arrays;

/**
 * Created by Administrator on 2015/5/19.
 */
public class IcbcParams extends Params {
    private int[][] types = new int[][]{
            {1, 2, 5, 6, 9, 18, 19, 24},       //签到
            {1, 2, 5, 6, 9, 24},       //签退
            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 24},       //圈存+冲正
            {1, 2, 5, 6, 7, 9, 20, 21, 22, 23, 24}  //对账
    };

    /**
     * 生成初始参数
     * @param i  0签到 1签退 2交易 3对账
     */
    public IcbcParams(Integer i) {
        Field[] fields = getClass().getFields();
        try {
            for (Field field : fields) {
                if (!field.isAnnotationPresent(ParamLength.class)) continue;
                ParamLength pl = field.getAnnotation(ParamLength.class);
                if (Arrays.binarySearch(types[i], pl.order()) >= 0)
                    field.set(this, "");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过请求返回的数据 生成返回参数
     * @param respStr   请求返回数据
     */
    public IcbcParams(String respStr) {
        int temp = 0;
        ParamLength pl;
        String code = respStr.substring(8, 12);
        int[] type = null;
        if (code.equals("8401"))
            type = types[0];
        else if (code.equals("8402"))
            type = types[1];
        else if (code.equals("8403") || code.equals("8404"))
            type = types[2];
        else type = types[3];
        Field[] fields = getClass().getFields();
        try {
            for (int i = 0; i < fields.length; i++) {
                if (Arrays.binarySearch(type, i + 1) < 0) continue;
                for (Field field : fields) {
                    if (!field.isAnnotationPresent(ParamLength.class)) continue;
                    pl = field.getAnnotation(ParamLength.class);
                    if (pl.order() == i + 1) {
                        byte[] bytes = new byte[pl.length()];
                        System.arraycopy(respStr.getBytes(), temp, bytes, 0, pl.length());
                        temp += pl.length();
                        field.set(this, new String(bytes).trim());
                        break;
                    }
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    //单位代码
    @ParamLength(length = 8, order = 1)
    public String schoolCode;

    //交易代码
    //签到	8401
    //答退	8402
    //转帐交易	8403
    //冲正交易	8404
    //清算交易	8405
    //对账请求	8407
    //对账确认	8408
    @ParamLength(length = 4, order = 2)
    public String transCode;

    //交易类型 10 充值交易 11 缴学费 12 清算
    @ParamLength(length = 2, order = 3)
    public String transType;

    //交易标志 0正交易 1反交易
    @ParamLength(length = 1, order = 4)
    public String transMark;

    //交易时间 HHmmss
    @ParamLength(length = 8, order = 5)
    public String transTime;

    //交易日期
    @ParamLength(length = 10, order = 6)
    public String transDate;

    //清算日期 yyyyMMdd
    @ParamLength(length = 10, order = 7)
    public String accDate;

    //圈存机编码
    @ParamLength(length = 10, order = 8)
    public String terminalNo;

    //响应代码
    @ParamLength(length = 5, order = 9)
    public String rtnCode;

    //商户交易流水号
    @ParamLength(length = 12, order = 10)
    public String transNo;

    //银行交易流水号
    @ParamLength(length = 12, order = 11)
    public String bankTransNo;

    //原商户交易流水号
    @ParamLength(length = 12, order = 12)
    public String oldTransNo;

    //一卡通编码
    @ParamLength(length = 16, order = 13)
    public String yktNo;

    //返回信息
    @ParamLength(length = 40, order = 14)
    public String rtnMsg;

    //银行账号密文
    @ParamLength(length = 48, order = 15)
    public String bankCardNo;

    //交易金额密文 单位分
    @ParamLength(length = 32, order = 16)
    public String money;

    //备注
    @ParamLength(length = 40, order = 17)
    public String note;

    //PKG密钥密文
    @ParamLength(length = 32, order = 18)
    public String pkgKey;

    //Mac密钥密文
    @ParamLength(length = 32, order = 19)
    public String macKey;

    //正交易总笔数密文
    @ParamLength(length = 16, order = 20)
    public String transCount;

    //正交易总金额密文
    @ParamLength(length = 32, order = 21)
    public String moneyCount;

    //备注1 -- 对账返回
    @ParamLength(length = 8, order = 22)
    public String note1;

    //备注2 -- 对账返回
    @ParamLength(length = 13, order = 23)
    public String note2;

    //Mac
    @ParamLength(length = 8, order = 24)
    public String mac;

    /**
     * 生成mac
     * @param type  0 使用交换密钥   其他 使用工作密钥
     * @return
     * @throws IllegalAccessException
     * @throws NativeException
     */
    public String genMac(Integer type) throws IllegalAccessException, NativeException {
        String str = toString();
        return IcbcNative.getMac(str.substring(0, str.length() - 8), type);
    }
}
